﻿using System;
using System.Drawing.Imaging;
using System.Drawing;

namespace CubeDetection
{
   public unsafe class ImageFilter
   {
      int[,] filterMask;
      int sum;

      
      public ImageFilter(int[,] FilterMask,int diff)
         :this(FilterMask)
         {
            sum = diff;
         }
      public ImageFilter(int[,] FilterMask)
      {
         filterMask = FilterMask;
         for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
               sum += FilterMask[i, j];
      }
      int threshold = 75;
      public int Threshold
      {
         get { return threshold; }
         set { threshold = value; }
      }
      public Bitmap Filter(Bitmap SourceBmp)
      {
         Bitmap DstBitmap = (Bitmap)SourceBmp.Clone();
         Graphics.FromImage(DstBitmap).FillRectangle(Brushes.DarkRed, 0, 0, DstBitmap.Width, DstBitmap.Height);
         BitmapData bData = DstBitmap.LockBits(new Rectangle(0, 0, DstBitmap.Width, DstBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
         BitmapData srcData = SourceBmp.LockBits(new Rectangle(0, 0, SourceBmp.Width, SourceBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

         byte* rgbData = (byte*)srcData.Scan0.ToPointer();
         rgb*[] pxcData = new rgb*[3];
         rgb* wData;
         byte* dstData = (byte*)bData.Scan0.ToPointer();
         int valR,valG,valB;
         for (int y = 1; y < DstBitmap.Height - 1; y++)
         {
            for (int x = 1; x < DstBitmap.Width - 1; x++)
            {
               valR = valG=valB= 0;
               pxcData[0] = ((rgb*)&rgbData[(y - 1) * srcData.Stride]) + x - 1;
               pxcData[1] = ((rgb*)&rgbData[(y ) * srcData.Stride]) + x - 1;
               pxcData[2] = ((rgb*)&rgbData[(y + 1) * srcData.Stride]) + x - 1;
               wData = ((rgb*)&dstData[y * bData.Stride]) + x;

               for (int i = 0; i < 3; i++)
               {
                  valR += pxcData[0][i].r * filterMask[0, i];
                  valG += pxcData[0][i].g * filterMask[0, i];
                  valB += pxcData[0][i].b * filterMask[0, i];

                  valR += pxcData[1][i].r * filterMask[1, i];
                  valG += pxcData[1][i].g * filterMask[1, i];
                  valB += pxcData[1][i].b * filterMask[1, i];

                  valR += pxcData[2][i].r * filterMask[2, i];
                  valG += pxcData[2][i].g * filterMask[2, i];
                  valB += pxcData[2][i].b * filterMask[2, i];
               }
               wData->r = (byte)(Math.Abs(valR / sum));
               wData->g = (byte)(Math.Abs(valG / sum));
               wData->b = (byte)(Math.Abs(valB / sum));
               if (wData->r > threshold || wData->g > threshold || wData->b > threshold)
               {
                  wData->r =
                  wData->g =
                  wData->b = 255;
               }
               else
               {
                  wData->r =
                  wData->g =
                  wData->b = 0;
               }
            }
         }




         DstBitmap.UnlockBits(bData);
         SourceBmp.UnlockBits(srcData);
         return DstBitmap;

      }

    
   }
}
